/**
 * 线工具
 */
class DrawLine {
  viewer: any;
  LineSource: any; // 容器

  handlerLine: any;
  linePoints: any;
  constructor(viewer: any, LineSource: any) {
    this.viewer = viewer;
    this.LineSource = LineSource;
  }

  // 绘制程序的准备工作，通过其他方式触发activate
  readyDrawLineHandler() {
    this.handlerLine = new Cesium.DrawHandler(
      this.viewer,
      Cesium.DrawMode.Line
    );
    this.handlerLine.activeEvt.addEventListener((isActive) => {
      if (isActive) {
        this.viewer.enableCursorStyle = false;
        this.viewer._element.style.cursor = "";
        document.documentElement.style.cursor = "pointer";
      } else {
        this.viewer.enableCursorStyle = true;
        document.documentElement.style.cursor = "";
      }
    });
    this.handlerLine.drawEvt.addEventListener((result) => {
      // 绘制结束（不是关闭绘制）
      this.linePoints = result.object.positions;
    });
  }

  // 开始绘制
  startDrawLine() {
    this.handlerLine.deactivate(); // 先触发一次关闭绘制
    this.handlerLine.clear(); // 先清除一次之前的点位
    this.handlerLine.activate(); // 触发绘制
  }

  // 清除已存在的点位 会同时关闭当前存在的绘制
  cleanDrawLine() {
    this.handlerLine.clear();
  }

  // 关闭绘制
  endDrawLine() {
    this.handlerLine.deactivate();
  }

  // 加载默认线条
  initShowPolyline(lineColor: string = "#00f", positions: any, id: string) {
    var material = new Cesium.PolylineGlowMaterialProperty({
      glowPower: 0.25,
      color: Cesium.Color.fromCssColorString(lineColor).withAlpha(0.9),
    });

    var bData = {
      id,
      shapeType: "Polyline",
      polyline: {
        positions: positions,
        clampToGround: true,
        width: 8,
        material: material,
      },
    };
    var entity = this.LineSource.entities.add(bData);
    return entity;
  }

  /**
   * 清除场景实体
   * @param id
   */
  clearLineHandler(id: string) {
    // this.LineSource.entities.removeAll() // 清除场景中所有的entity实体
    // this.LineSource.entities.remove(line) // 传入指定的实体删除
    this.LineSource.entities.remove(this.LineSource.entities.getById(id)); // 根据id获取到对应的实体再触发删除
  }

  /**
   * 绘制发光的线
   * @param {string} id
   * @param {string} name
   * @param {array} positions [第一个点经度lon, 第一个点纬度lat, 第二个点经度lon, 第二个点纬度lat]
   * @param {string} color
   */
  drawGlowingLineHandler(
    id: string,
    name: string,
    positions: [],
    color: string
  ) {
    this.LineSource.entities.add({
      id,
      name,
      polyline: {
        positions: Cesium.Cartesian3.fromDegreesArray(positions),
        width: 5,
        followSurface: true,
        material: new Cesium.PolylineGlowMaterialProperty({
          glowPower: 0.2,
          color: Cesium.Color.fromCssColorString(color),
        }),
      },
    });
  }

  /**
   * 绘制指定颜色的线
   * @param {string} id
   * @param {string} name
   * @param {array} positions [第一个点经度lon, 第一个点纬度lat, 第二个点经度lon, 第二个点纬度lat]
   * @param {string} color
   */
  drawSpecifyColorLineHandler(
    id: string,
    name: string,
    positions: [],
    color: string
  ) {
    this.LineSource.entities.add({
      id,
      name,
      polyline: {
        positions: Cesium.Cartesian3.fromDegreesArray(positions),
        width: 5,
        material: Cesium.Color.fromCssColorString(color),
      },
    });
  }

  /**
   * 绘制指定颜色指定边框颜色的线
   * @param {string} id
   * @param {string} name
   * @param {array} coordinates 经度，纬度和高度值的列表。值交替显示[经度，纬度，高度，经度，纬度，高度...]
   * @param {string} color 指定颜色
   * @param {string} outlineColor 指定边框颜色
   */
  drawSpecifyColorAndOutlineColorLineHandler(
    id: string,
    name: string,
    coordinates: [],
    color: string,
    outlineColor: string
  ) {
    this.LineSource.entities.add({
      id,
      name,
      polyline: {
        positions: Cesium.Cartesian3.fromDegreesArrayHeights(coordinates),
        width: 10, // 线宽
        material: new Cesium.PolylineOutlineMaterialProperty({
          color: Cesium.Color.fromCssColorString(color),
          outlineWidth: 2, // 边框的宽度
          outlineColor: Cesium.Color.fromCssColorString(outlineColor),
        }),
      },
    });
  }

  /**
   * 绘制指定颜色的箭头静态指示线
   * @param {string} id
   * @param {string} name
   * @param {array} coordinates 经度，纬度和高度值的列表。值交替显示[经度，纬度，高度，经度，纬度，高度...]
   * @param {string} color 指定颜色
   */
  drawSpecifyColorArrowStaticStateLineHandler(
    id: string,
    name: string,
    coordinates: [],
    color: string
  ) {
    this.LineSource.entities.add({
      id,
      name,
      polyline: {
        positions: Cesium.Cartesian3.fromDegreesArrayHeights(coordinates),
        width: 10,
        followSurface: false,
        material: new Cesium.PolylineArrowMaterialProperty(
          Cesium.Color.fromCssColorString(color)
        ),
      },
    });
  }

  /**
   * 绘制动态的线
   * @param {string} id
   * @param {string} name
   * @param {array} coordinates 经度和纬度值列表。值交替显示[经度，纬度，经度，纬度...]
   * @param {string} color 指定颜色
   * @param {string} outlineColor 指定边框颜色
   */
  drawDashedLineHandler(
    id: string,
    name: string,
    coordinates: [],
    color: string,
    outlineColor: string
  ) {
    this.LineSource.entities.add({
      id,
      name,
      polyline: {
        positions: Cesium.Cartesian3.fromDegreesArray(coordinates),
        width: 10,
        hMax: 500000,
        material: new Cesium.PolylineDynamicMaterialProperty({
          color: Cesium.Color.fromCssColorString(color),
          outlineWidth: 1,
          outlineColor: Cesium.Color.fromCssColorString(outlineColor),
        }),
      },
    });
  }

  /**
   *
   * @param {string} id
   * @param {string} name
   * @param {array} coordinates 经度，纬度和高度值的列表。值交替显示[经度，纬度，高度，经度，纬度，高度...]
   * @param {string} color 指定颜色
   * @param {number} time
   */
  drawFlowingLineHandler(
    id: string,
    name: string,
    coordinates: [],
    color: string,
    time: number
  ) {
    this.polylineTrailLinkMaterialProperty();
    this.LineSource.entities.add({
      id,
      name,
      polyline: {
        positions: Cesium.Cartesian3.fromDegreesArrayHeights(coordinates),
        width: 10,
        material: new Cesium.PolylineTrailLinkMaterialProperty(
          Cesium.Color.fromCssColorString(color),
          time //ms
        ), //修改抛物线材质
      },
    });
  }

  // 将图片作为材质添加到cesium中，供绘制流动的线段使用
  polylineTrailLinkMaterialProperty() {
    // 流动线纹理
    function PolylineTrailLinkMaterialProperty(color, duration) {
      this._definitionChanged = new Cesium.Event();
      this._color = undefined;
      this._colorSubscription = undefined;
      this.color = color;
      this.duration = duration;
      this._time = new Date().getTime();
    }

    Object.defineProperties(PolylineTrailLinkMaterialProperty.prototype, {
      isConstant: {
        get: function () {
          return false;
        },
      },
      definitionChanged: {
        get: function () {
          return this._definitionChanged;
        },
      },
      color: Cesium.createPropertyDescriptor("color"),
    });

    PolylineTrailLinkMaterialProperty.prototype.getType = function (time) {
      return "PolylineTrailLink";
    };
    PolylineTrailLinkMaterialProperty.prototype.getValue = function (
      time,
      result
    ) {
      if (!Cesium.defined(result)) {
        result = {};
      }
      result.color = Cesium.Property.getValueOrClonedDefault(
        this._color,
        time,
        Cesium.Color.WHITE,
        result.color
      );
      result.image = Cesium.Material.PolylineTrailLinkImage;
      result.time =
        ((new Date().getTime() - this._time) % this.duration) / this.duration;
      return result;
    };
    PolylineTrailLinkMaterialProperty.prototype.equals = function (other) {
      return (
        this === other ||
        (other instanceof PolylineTrailLinkMaterialProperty &&
          Cesium.Property.equals(this._color, other._color))
      );
    };

    Cesium.PolylineTrailLinkMaterialProperty =
      PolylineTrailLinkMaterialProperty;
    Cesium.Material.PolylineTrailLinkType = "PolylineTrailLink";
    Cesium.Material.PolylineTrailLinkImage =
      ""; //图片 图片为箭头
    Cesium.Material.PolylineTrailLinkSource =
      "czm_material czm_getMaterial(czm_materialInput materialInput)\n\
{\n\
    czm_material material = czm_getDefaultMaterial(materialInput);\n\
    vec2 st = materialInput.st;\n\
    vec4 colorImage = texture2D(image, vec2(fract(st.s - time), st.t));\n\
    material.alpha = colorImage.a * color.a;\n\
    material.diffuse = (colorImage.rgb+color.rgb)/2.0;\n\
    return material;\n\
}";

    Cesium.Material._materialCache.addMaterial(
      Cesium.Material.PolylineTrailLinkType,
      {
        fabric: {
          type: Cesium.Material.PolylineTrailLinkType,
          uniforms: {
            color: new Cesium.Color(255.0, 255.0, 255.0, 1),
            image: Cesium.Material.PolylineTrailLinkImage,
            time: 0,
          },
          source: Cesium.Material.PolylineTrailLinkSource,
        },
        translucent: function (material) {
          return true;
        },
      }
    );
  }
}

export default DrawLine;
